package com.ctshk.rpc.goods.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.GlobalConstants;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.goods.dto.CommodityClassificationAllLevelListDTO;
import com.ctshk.rpc.goods.dto.CommodityClassificationDTO;
import com.ctshk.rpc.goods.dto.CommodityClassificationLevelTwoDTO;
import com.ctshk.rpc.goods.entity.CommodityClassification;
import com.ctshk.rpc.goods.mapper.CommodityClassificationMapper;
import com.ctshk.rpc.goods.req.CommodityClassificationAddReq;
import com.ctshk.rpc.goods.req.CommodityClassificationPageReq;
import com.ctshk.rpc.goods.service.ICommodityClassificationService;
import com.ctshk.rpc.goods.service.IESClassificationService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-08
 */
@DubboService
public class CommodityClassificationServiceImpl extends ServiceImpl<CommodityClassificationMapper, CommodityClassification> implements ICommodityClassificationService {

	@Autowired
	private CommodityClassificationMapper mapper;

	@DubboReference
	private ISysPermissionService sysPermissionService;

	@DubboReference
	private IESClassificationService iesClassificationService;

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void addCommodityClassification(CommodityClassificationAddReq addReq, Long userId) throws Exception {
		List<CommodityClassificationDTO> currentLeveData = null;
		List<String> classNames = null;
		CommodityClassification classification = new CommodityClassification();
		if (1 == addReq.getCurrentLevelPage()) {
			currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), null);
			classNames = currentLeveData.stream().map(obj -> obj.getClassificationName()).collect(Collectors.toList());
			if (classNames.contains(addReq.getClassificationName())) {
				throw new BusinessException(SystemError.MALL_MERCHANDISE_23025);
			}
			BeanUtils.copyProperties(addReq, classification, EntityUtil.getNullPropertyNames(addReq));
			classification.setClassificationLevel(addReq.getCurrentLevelPage());
		} else {
			if (null == addReq.getParentId()) {
				throw new BusinessException(SystemError.MALL_MERCHANDISE_23026);
			}
			currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), addReq.getParentId());
			classNames = currentLeveData.stream().map(obj -> obj.getClassificationName()).collect(Collectors.toList());
			if (classNames.contains(addReq.getClassificationName())) {
				throw new BusinessException(SystemError.MALL_MERCHANDISE_23027);
			}
			BeanUtils.copyProperties(addReq, classification, EntityUtil.getNullPropertyNames(addReq));
			classification.setClassificationLevel(2); // 不是一級分類添加，一定為2級分類
		}
		LocalDateTime now=LocalDateTime.now();
		classification.setId(SnowflakeIdWorker.nextId());
		classification.setIsDisplay(addReq.getIsDisplay());
		classification.setSort(addReq.getSort());
		classification.setStatus(addReq.getStatus());
		classification.setCreateId(userId);
		classification.setGmtCreate(now);
		classification.setModifiedId(userId);
		classification.setGmtModified(now);
		classification.setIsDisplay(0); // 默认不显示在首页
		classification.setIsDeleted(IsDeletedCode.NO.getCode());
		mapper.insert(classification);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void updateCommodityClassification(CommodityClassificationAddReq addReq, Long userId) throws Exception {
		List<CommodityClassificationDTO> currentLeveData = null;
		LocalDateTime now=LocalDateTime.now();
		Map<String, Long> map = new HashMap<String, Long>();
		CommodityClassification dbClassification = mapper.selectById(addReq.getId());
		BeanUtils.copyProperties(addReq, dbClassification, EntityUtil.getNullPropertyNames(addReq));
		if (null != addReq.getCurrentLevelPage() && 1 == addReq.getCurrentLevelPage()) {
			currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), null);
			map = currentLeveData.stream().collect(Collectors.toMap(CommodityClassificationDTO::getClassificationName, CommodityClassificationDTO::getId));
			if (map.containsKey(dbClassification.getClassificationName())) {
				Long key = map.get(dbClassification.getClassificationName());
				if (key.longValue() != dbClassification.getId().longValue()) {
					throw new BusinessException(SystemError.MALL_MERCHANDISE_23025);
				}
			}
		} else {
//			if (null == addReq.getParentId() && addReq.getClassificationLevel() != null && addReq.getClassificationLevel() != 1) {
//				throw new BusinessException(SystemError.MALL_MERCHANDISE_23026);
//			}
			currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), addReq.getParentId());
			map = currentLeveData.stream().collect(Collectors.toMap(CommodityClassificationDTO::getClassificationName,CommodityClassificationDTO::getId));
			if (map.containsKey(dbClassification.getClassificationName())) {
				Long key = map.get(dbClassification.getClassificationName());
				if (key.longValue() != dbClassification.getId().longValue()) {
					throw new BusinessException(SystemError.MALL_MERCHANDISE_23027);
				}
			}
			// 修改子集，父级对象也更新修改时间
			CommodityClassification commodityClassification = new CommodityClassification();
			commodityClassification.setModifiedId(userId);
			commodityClassification.setGmtModified(now);
			commodityClassification.setId(addReq.getParentId());
			mapper.updateById(commodityClassification);
		}
		dbClassification.setModifiedId(userId);
		dbClassification.setGmtModified(now);
		mapper.updateById(dbClassification);
		try{
			iesClassificationService.updateClassificationES();
		}catch (Exception e){
			log.error("【中旅到家后台-B端-分类】更新分类列表失败");
		}
	}

	@Override
	public PageResponse<CommodityClassificationDTO> findCommodityClassification(CommodityClassificationPageReq pageReq, TokenUser tokenUser) {
		Result<List<Long>> permissionResult = sysPermissionService.queryPermission(pageReq.getMenuId(), tokenUser.getId());
		if (!permissionResult.isSuccess()) {
			SystemError result = SystemError.getDefined(permissionResult.getCode());
			throw new BusinessException(result);
		}
		//不是管理员
		if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {
			pageReq.setIsNotAdmin(1);
			String ids = "";
			List<Long> data = permissionResult.getData();
			if(data != null && data.size() >0){
				for (Long datum : data) {
					ids += datum + ",";
				}
			}
			if(ids.length() > 0){
				ids = ids.substring(0, ids.length() - 1);
			}
			pageReq.setUserIds(ids);
		}

		IPage<CommodityClassificationDTO> page = new Page<CommodityClassificationDTO>(pageReq.getPageNo(),pageReq.getPageSize());
		IPage<CommodityClassificationDTO> iPage = mapper.findCommodityClassificationByCondition(page, pageReq);
		List<CommodityClassificationDTO> recordsList = iPage.getRecords();
		List<CommodityClassificationDTO> pageDTOList = EntityUtil.copyList(recordsList, CommodityClassificationDTO.class);
		return new PageResponse<>(pageDTOList, iPage.getCurrent() == 1,
				iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()),
				iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
	}

	@Override
	public List<CommodityClassificationDTO> findClassificationNameList(Long menuId, TokenUser tokenUser) {
		// 校验权限
		Result<List<Long>> permissionResult = sysPermissionService.queryPermission(menuId, tokenUser.getId());
		if (!permissionResult.isSuccess()) {
			SystemError result = SystemError.getDefined(permissionResult.getCode());
			throw new BusinessException(result);
		}
		String userIds = "";
		//不是管理员
		if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {
			List<Long> data = permissionResult.getData();
			if(data != null && data.size() >0){
				for (Long datum : data) {
					userIds += datum + ",";
				}
			}
			if(userIds.length() > 0){
				userIds = userIds.substring(0, userIds.length() - 1);
			}
		}

		return mapper.findOneLeveClassificationNameList(userIds);
	}

	@Override
	public List<CommodityClassificationAllLevelListDTO> findClassificationByAllLevel(LocalDateTime now, Long menuId, TokenUser tokenUser) {

		// 校验权限
		Result<List<Long>> permissionResult = sysPermissionService.queryPermission(menuId, tokenUser.getId());
		if (!permissionResult.isSuccess()) {
			SystemError result = SystemError.getDefined(permissionResult.getCode());
			throw new BusinessException(result);
		}
		String userIds = "";
		//不是管理员
		if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {
			List<Long> data = permissionResult.getData();
			if(data != null && data.size() >0){
				for (Long datum : data) {
					userIds += datum + ",";
				}
			}
			if(userIds.length() > 0){
				userIds = userIds.substring(0, userIds.length() - 1);
			}
		}

		List<CommodityClassificationAllLevelListDTO> dbLevelOneData = mapper.findClassificationByLevelOne(now, userIds);
		List<CommodityClassificationLevelTwoDTO> dbLevelTwoData = mapper.findClassificationByLevelTwo(now);
		Map<String, List<CommodityClassificationLevelTwoDTO>> levelTwo = dbLevelTwoData.stream().collect(Collectors.groupingBy(levelOjb -> levelOjb.getParentId().toString()));
		for (CommodityClassificationAllLevelListDTO levelOne: dbLevelOneData) {
			levelOne.setLevelTwo(null);
			if (levelTwo.containsKey(levelOne.getId().toString())){
				List<CommodityClassificationLevelTwoDTO> levelTwos= levelTwo.get(levelOne.getId().toString());
				levelOne.setLevelTwo(levelTwos);
			}
		}
		return dbLevelOneData;
	}

	@Override
	public Boolean updateClassfincationStatus(CommodityClassificationAddReq req) {
		Integer integer = mapper.updateClassfincationStatus(req.getId(), req.getStatus(), req.getIsDisplay());
		try{
			iesClassificationService.updateClassificationES();
		}catch (Exception e){
			log.error("【中旅到家后台-B端-分类】更新分类列表失败");
		}
		if(integer > 0){
			return true;
		}
		return false;
	}

	@Override
	public List<JSONObject> findCommodityClassficationListAll(Long menuId, TokenUser tokenUser) {
		Result<List<Long>> permissionResult = sysPermissionService.queryPermission(menuId, tokenUser.getId());
		if (!permissionResult.isSuccess()) {
			SystemError result = SystemError.getDefined(permissionResult.getCode());
			throw new BusinessException(result);
		}
		String userIds = "";
		//不是管理员
		if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {

			List<Long> data = permissionResult.getData();
			if(data != null && data.size() >0){
				for (Long datum : data) {
					userIds += datum + ",";
				}
			}
			if(userIds.length() > 0){
				userIds = userIds.substring(0, userIds.length() - 1);
			}
		}
		return mapper.findCommodityClassficationListAll(userIds);
	}
}